<?php

namespace app\api\model;

use app\common\enums\StatusEnum;
use app\common\service\Html;

class TieBa extends \app\common\model\TieBa
{
    /**
     * 帖子列表
     * @param int $oauthId 授权登录的id
     * @param int $typeId 帖子类型id
     * @param $page
     * @param $size
     * @param $user array 指定用户
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getList($oauthId, $typeId, $page, $size, $user = [])
    {
        $offset = ($page - 1) * $size;

        $sql = static::field('o.id AS uid, o.nickname,o.phone, o.head_img AS headImg, t.id AS tieId, tt.name, t.content, t.praise, t.is_top AS isTop,  t.create_time AS createTime')
            ->alias('t')
            ->join('oauth o', 't.oauth_id = o.id')
            ->join('tie_ba_type tt', 't.type_id = tt.id')
            ->where([
                't.is_draft' => self::DRAFT_NO,
                't.check_status' => self::CHECK_PASS,
                'tt.status' => StatusEnum::ENABLED,
                'o.status' => StatusEnum::ENABLED
            ]);

        if ($typeId > 0) {
            $sql->where(['type_id' => $typeId]);
        }

        $userInfo = [];
        if ($user) {
            // 加上个人id搜索帖子
            $sql->where(['t.oauth_id' => $user['id']]);

            // 不是本人，判断是否已经关注这个人
            $isFocus = 0; // 未关注
            if ($oauthId != $user['id']) {
                $focus = OauthFocus::getOne($oauthId, $user['id']);
                if ($focus) {
                    $isFocus = 1; // 已关注
                }
            } else {
                $isFocus = 2; // 本人
            }

            $userInfo = [
                'uid' => $user['id'],
                'isFocus' => $isFocus, // 是否已经关注这个人
                'nickname' => $user['nickname'],
                'sex' => $user['sex'],
                'area' => $user['address'],
                'headImg' => $user['head_img'],
                'signature' => $user['signature'],
            ];
        }

        $model = $sql->order(['t.is_top' => 'desc', 't.create_time' => 'desc'])
            ->limit($offset, $size)
            ->select()
            ->toArray();

        // 获取帖子的评论数、点赞数、上传的文件
        $model = self::getTieData($oauthId, $model);
        // 未读条数
        $unRead = TieBaComment::unRead($oauthId);
        return [
            'unRead' => $unRead,
            'userInfo' => $userInfo,
            'list' => $model,
            'count' => $sql->count()
        ];
    }

    /**
     * 处理帖子的点赞数、评论数、上传文件
     * @param $oauthId int 登录用户id
     * @param $model
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getTieData($oauthId, $model)
    {
        $tieIds = [];
        // 获取帖子对应的图片 或者 视频
        foreach ($model as $key => $value) {
            $model[$key]['praise'] = ($value['praise'] > self::MAX_NUM) ? self::MAX_NUM . '+' : $value['praise'];
            $model[$key]['content'] = Html::encode($value['content']);
            $tieIds[$value['tieId']] = $value['tieId'];
        }

        if ($tieIds) {
            // 每条帖子下面的文件
            $files = TieBaFile::getListByTie($tieIds);
            // 每条帖子的总评论数
            $comments = TieBaComment::getCount($tieIds);
            // 登录用户已经点赞的帖子
            $isPraise = TieBaCollect::getByTie($oauthId, $tieIds, TieBaCollect::TYPE_PRAISE);
            foreach ($model as $key => $value) {
                $model[$key]['canDelete'] = ($value['uid'] == $oauthId) ? 1 : 0;
                $model[$key]['createTime'] = get_datetime($value['createTime']);
                // 是否已经点赞
                $model[$key]['isPraise'] = isset($isPraise[$value['tieId']]) ? 1 : 0;
                $comment = isset($comments[$value['tieId']]) ? $comments[$value['tieId']] : 0;
                $model[$key]['comments'] = ($comment > self::MAX_NUM) ? self::MAX_NUM . '+' : $comment;
                $model[$key]['files'] = isset($files[$value['tieId']]) ? $files[$value['tieId']] : [];
            }
        }

        return $model;
    }

    /**
     * 根据id获取帖子
     * @param $id
     * @return array|\PDOStatement|string|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getOneById($id)
    {
        $model = static::field('t.id AS tieId, t.oauth_id AS uid, o.nickname, o.head_img AS headImg, tt.name, t.content, t.praise, t.is_top AS isTop, t.create_time AS createTime')
            ->alias('t')
            ->join('oauth o', 't.oauth_id = o.id')
            ->join('tie_ba_type tt', 't.type_id = tt.id')
            ->where([
                't.id' => $id,
                't.is_draft' => self::DRAFT_NO,
                't.check_status' => self::CHECK_PASS,
                'tt.status' => StatusEnum::ENABLED,
                'o.status' => StatusEnum::ENABLED
            ])->find();
        if ($model) {
            $model['content'] = Html::encode($model['content']);
        }
        return $model;
    }

    /**
     * 帖子详情
     * @param int $id 帖子id
     * @param int $oauthId 登录用户的id
     * @param int $commentId 评论或者回复的id
     * @param $page
     * @param $size
     * @return array|\PDOStatement|string|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getOne($id, $oauthId, $commentId, $page, $size)
    {
        $model = self::getOneById($id);

        if ($model) {
            $model = $model->toArray();

            // 我的消息列表点进来的，根据评论id更新一下已读状态
            if ($commentId > 0) {
                TieBaComment::updateRead($oauthId, $commentId);
            }

            // 获取帖子的点赞数、评论数、上传的文件
            $tmp = self::getTieData($oauthId, [$model]);
            $model = $tmp[0];

            $collect = TieBaCollect::getOne($oauthId, $id, TieBaCollect::TYPE_COLLECT);
            // 是否已经收藏
            $model['isCollect'] = $collect ? 1 : 0;
            // 评论列表
            $model['commentList'] = TieBaComment::getListByTie($id, $page, $size);
        }
        return $model ? $model : [];
    }

    /**
     *  发表帖子
     * @param $oauthId
     * @param $typeId
     * @param $content
     * @param $isDraft
     * @param array $files
     * @return array
     * @throws \Exception
     */
    public static function addOne($oauthId, $typeId, $content, $isDraft, $files = [])
    {
        $model = static::create([
            'oauth_id' => $oauthId,
            'type_id' => $typeId,
            'content' => $content,
            'is_draft' => $isDraft
        ]);

        if (!empty($files)) {
            $insertFiles = [];
            foreach ($files as $key => $value) {
                $insertFiles[] = [
                    'tie_id' => $model->id,
                    'type' => $value['type'],
                    'file' => $value['file'],
                ];
            }
            if ($insertFiles) {
                $fileModel = new TieBaFile();
                $fileModel->saveAll($insertFiles);
            }
        }

        // 加积分
        $integralType = OauthIntegral::TYPE_TIE;
        $config = Config::integralGet($integralType);
        // 帖子满50个字，添加积分记录
        if (mb_strlen($content, 'UTF-8') >= $config['wordCount']) {
            $addNum = OauthIntegral::getNum($oauthId, $integralType, $config);
            OauthIntegral::addOne($oauthId, $integralType, $addNum);
        }

        return isset($model->id) ? [
            'tieId' => $model->id
        ] : [];
    }

    /**
     * 我的帖子数量
     * @param $oauthId
     * @return float|string
     */
    public static function getCountMine($oauthId)
    {
        return static::where([
            'oauth_id' => $oauthId,
            'is_draft' => self::DRAFT_NO,
            'check_status' => self::CHECK_PASS,
        ])->count();
    }

    /**
     * 删除自己的帖子
     * @param $id
     * @param $oauthId
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public static function deleteOne($id, $oauthId)
    {
        static::where([
            'id' => $id,
            'oauth_id' => $oauthId
        ])->delete();

        // 顺便删除帖子的文件
        TieBaFile::deleteByTie($id);
    }

    /**
     * 获取一条帖子
     * @param $id
     * @return array|\PDOStatement|string|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getOneTie($id)
    {
        return static::field('id, praise')
            ->where([
                'id' => $id,
                'is_draft' => self::DRAFT_NO,
                'check_status' => self::CHECK_PASS
            ])->find();
    }

    /**
     * 给指定帖子点赞数+1
     * @param $id
     * @param $num
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function updatePraise($id, $num)
    {
        $model = self::getOneTie($id);
        if ($model && ($model->praise + $num >= 0)) {
            $model->praise += $num;
            $model->save();
        }
    }

    /**
     * 计算每个帖子类型的参与人数
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function countByTie()
    {
        return static::field('type_id, COUNT(*) AS count')
            ->where([
                'is_draft' => self::DRAFT_NO,
                'check_status' => self::CHECK_PASS
            ])->group('type_id')
            ->select()
            ->column('count', 'type_id');
    }
}